package cn.cm.config;

import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.HashMap;
import java.util.Map;

/**
 * @author shikundai
 * @date 2021/6/28
 * @time 16:15
 * @description: Shiro配置文件
 */
@Configuration
public class ShiroConfig {
    /**
     * 凭证匹配器
     * （由于我们的密码校验交给Shiro的SimpleAuthenticationInfo进行处理了）
     * HashedCredentialsMatcher说明：
     * 用户传入的token先经过shiroRealm的doGetAuthenticationInfo方法
     * 此时token中的密码为明文。
     * 再经由HashedCredentialsMatcher加密password与查询用户的结果password做对比。
     * new SimpleHash("SHA-256", password, null, 1024).toHex();
     * @return
     */
    @Bean
    public HashedCredentialsMatcher hashedCredentialsMatcher(){
        /*
         *（1）创建加密对象
         *（2）设置加密规则
         *（3）返回该对象
         */
//        （1）创建加密对象
        HashedCredentialsMatcher hashedCredentialsMatcher=new HashedCredentialsMatcher();
//        (2)设置加密算法
        hashedCredentialsMatcher.setHashAlgorithmName("MD5");
//       （3）设置加密次数
        hashedCredentialsMatcher.setHashIterations(999);

        return hashedCredentialsMatcher;
    }

    /**
     * 描述：创建Realm
     * @author shikundai
     * @date 2021/3/24
     * @time 11:45
     */
    @Bean
    public ShiroRealm shiroRealm(){
        /*
         *（1）创建ShiroRealm对象
         *（2）设置该对象的加密方式
         *（3）返回该对象
         */
//        （1）创建ShiroRealm对象
        ShiroRealm shiroRealm=new ShiroRealm();
//        (2)设置加密方式
        shiroRealm.setCredentialsMatcher(hashedCredentialsMatcher());
        return shiroRealm;
    }
    /**
     * 描述：创建securityManager
     * @author shikundai
     * @date 2021/3/24
     * @time 11:46
     */
    @Bean
    public DefaultWebSecurityManager securityManager(ShiroRealm shiroRealm){
        /*
         *（1）创建DefaultWebSecurityManager对象
         *（2）设置realm
         *（3）返回该对象
         */
//       （1）创建DefaultWebSecurityManager对象
        DefaultWebSecurityManager defaultWebSecurityManager=new DefaultWebSecurityManager();
//       （2）设置realm
        defaultWebSecurityManager.setRealm(shiroRealm());
//      （3）返回对象
        return defaultWebSecurityManager;
    }

    /**
     * 描述：创建过滤器
     * @author shikundai
     * @date 2021/3/24
     * @time 11:43
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager){
        //（1）创建ShiroFilterFactoryBean
        ShiroFilterFactoryBean shiroFilterFactoryBean=new ShiroFilterFactoryBean();
        //（2）设置securityManager
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //（3）设置自定义拦截器
        Map<String , Filter> filterMap=new HashMap<>();
        filterMap.put("authc",new LoginFilter());
        shiroFilterFactoryBean.setFilters(filterMap);

        //（4）设置放行的页面
        Map<String,String> filterChain=new HashMap<>();

        //测试路径直接放行
        filterChain.put("/test/**","anon");
        filterChain.put("/user/login","anon");
        filterChain.put("/user/regist","anon");
        filterChain.put("/user/add","anon");

        //放行Swagger2页面，需要放行这些
        filterChain.put("/swagger-ui.html","anon");
        filterChain.put("/swagger/**","anon");
        filterChain.put("/webjars/**", "anon");
        filterChain.put("/swagger-resources/**","anon");
        filterChain.put("/v2/**","anon");
        filterChain.put("/static/**", "anon");
        filterChain.put("/doc.html","anon");
        //所有路径认证访问
        filterChain.put("/**","authc");


        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChain);

        //（5）设置需要认证访问的路径
        return shiroFilterFactoryBean;
    }




}
